package utilities;

import com.googlecode.javacpp.Loader;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;
import static com.googlecode.javacv.cpp.opencv_core.*;

/**
 *
 * @author Bhagya
 */
public class FindContours {

    double largest, result1 = 0, secondLargest;
    private CvSeq largestContour;
    private CvSeq secondLargestContour;
CvMemStorage storage = CvMemStorage.create();
    public int findLargeContours(IplImage image) {

        // Returns 2: If found 2 fingers
        // Returns 1: If found 1 finger
        // Returns 0: If nothing found or largest area is soo small
        
        largest = 0;
        secondLargest = 0;
        largestContour = new CvSeq(null);
        secondLargestContour = new CvSeq(null);
        CvSeq contours = new CvSeq(null);
        final int MIN_CONTOUR_AREA = 500;
        final int MAX_AREA_DIFF = 4000;

        int numCont = cvFindContours(image, storage, contours, Loader.sizeof(CvContour.class), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);

        if (numCont == 0 || contours == null || contours.isNull()) {
           // cvReleaseMemStorage(storage);
            return 0;

        } else if (numCont == 1) {

            largest = cvContourArea(contours, CV_WHOLE_SEQ, 0);
            if (largest < MIN_CONTOUR_AREA) {
               // cvReleaseMemStorage(storage);
                return 0;

            } else {
                largestContour = contours;
             //   cvReleaseMemStorage(storage);
                return 1;
            }

        } else {

            while (contours != null && !contours.isNull()) {

                result1 = cvContourArea(contours, CV_WHOLE_SEQ, 0);

                if (result1 > largest) {
                    secondLargest = largest;
                    largest = result1;
                    largestContour = contours;
                }

                if (secondLargest < result1 && largest != result1) {
                    secondLargest = result1;
                    secondLargestContour = contours;
                }
                contours = contours.h_next();
            }

            if (largest < MIN_CONTOUR_AREA) {
              //  cvReleaseMemStorage(storage);
                return 0;

            } else {
                double areaDiff = largest - secondLargest;

                if (areaDiff < MAX_AREA_DIFF) { // This should be defined well in order to capture 2 fingers
                 //   cvReleaseMemStorage(storage);
                    return 2;

                } else {
                    secondLargestContour.setNull();
                //    cvReleaseMemStorage(storage);
                    return 1;
                }
            }
        }
    }

    public CvSeq getLargestContour() {
        return largestContour;
    }

    public CvSeq getSecondLargestContour() {
        return secondLargestContour;
    }
}
